import { PlayerModel } from "core/model/playerModel";
import route from "core/route/route";
import { GameRouteData } from "core/utils/localApi";
import Random from "core/utils/random";
import { nbase64, nbase642 } from 'core/utils/newEnco'
import utils from "./utils/utils";
import { gameConfigHandle } from "./config/gameConfig";

// 实现 find 方法
if (!Array.prototype.find) {
    Array.prototype.find = function (callback, thisArg) {
        for (var i = 0; i < this.length; i++) {
            if (callback.call(thisArg, this[i], i, this)) {
                return this[i];
            }
        }
        return undefined;
    };
}

// 实现 findIndex 方法
if (!Array.prototype.findIndex) {
    Array.prototype.findIndex = function (callback, thisArg) {
        for (var i = 0; i < this.length; i++) {
            if (callback.call(thisArg, this[i], i, this)) {
                return i;
            }
        }
        return -1;
    };
}

// 实现 map 方法
if (!Array.prototype.map) {
    Array.prototype.map = function (callback, thisArg) {
        var result = [];
        for (var i = 0; i < this.length; i++) {
            result.push(callback.call(thisArg, this[i], i, this));
        }
        return result;
    };
}

// 实现 forEach 方法
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (callback, thisArg) {
        for (var i = 0; i < this.length; i++) {
            callback.call(thisArg, this[i], i, this);
        }
    };
}

if (!Array.prototype.fill) {
    Array.prototype.fill = function (value, start, end) {
        // 检查调用 fill 的对象是否是数组
        if (this == null) {
            throw new TypeError('this is null or not defined');
        }

        var array = Object(this); // 确保是对象
        var length = array.length >>> 0; // 保证 length 是无符号整数

        // 设置起始索引，默认为 0
        var startIdx = start >> 0 || 0;
        // 如果 start 为负数，从 length + start 开始
        startIdx = startIdx < 0 ? Math.max(length + startIdx, 0) : Math.min(startIdx, length);

        // 设置结束索引，默认为数组长度
        var endIdx = end === undefined ? length : end >> 0;
        // 如果 end 为负数，从 length + end 结束
        endIdx = endIdx < 0 ? Math.max(length + endIdx, 0) : Math.min(endIdx, length);

        // 填充数组
        for (var i = startIdx; i < endIdx; i++) {
            array[i] = value;
        }

        return array;
    };
}
if (!Array.prototype.includes) {
    Array.prototype.includes = function (searchElement, fromIndex) {
        var len = this.length;

        // 处理 fromIndex
        var startIndex = fromIndex || 0;
        // 处理负数的 startIndex
        if (startIndex < 0) {
            startIndex = Math.max(0, len + startIndex);
        }

        for (var i = startIndex; i < len; i++) {
            // 使用 Object.is 来比较值
            if (this[i] === searchElement || (searchElement !== searchElement && this[i] !== this[i])) {
                return true;
            }
        }
        return false;
    };
}

// 实现 Object.keys
if (!Object.keys) {
    Object.keys = function (obj) {
        if (obj === null || typeof obj !== 'object') {
            throw new TypeError('Object.keys called on non-object');
        }
        var keys = [];
        for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                keys.push(key);
            }
        }
        return keys;
    };
}

// 实现 Object.values
if (!Object.values) {
    Object.values = function (obj) {
        if (obj === null || typeof obj !== 'object') {
            throw new TypeError('Object.values called on non-object');
        }
        var values = [];
        for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                values.push(obj[key]);
            }
        }
        return values;
    };
}

// 实现 Object.entries
if (!Object.entries) {
    Object.entries = function (obj) {
        if (obj === null || typeof obj !== 'object') {
            throw new TypeError('Object.entries called on non-object');
        }
        var entries = [];
        for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                entries.push([key, obj[key]]);
            }
        }
        return entries;
    };
}

// 实现 Object.assign
if (!Object.assign) {
    Object.assign = function (target) {
        if (target === null || typeof target !== 'object') {
            throw new TypeError('Object.assign target must be an object');
        }
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            if (source !== null && typeof source === 'object') {
                for (var key in source) {
                    if (Object.prototype.hasOwnProperty.call(source, key)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        return target;
    };
}


class FUserData {
    playerCopy: string
    setConfigTime: number
    playerStrH: string
    waitEncodeData: string
}
let plen = 0
declare let gmessageCb: (message: string) => void
declare let deMessageCb: (message: string, key: string) => string
declare let enMessageCb: (message: string, key: string) => string
let fuserData = new FUserData()

function postMessage(msg) {
    gmessageCb(JSON.stringify(msg))
}

export function wmessage(messageStr: string) {
    let msg = JSON.parse(messageStr);
    if (msg.fmessageID) {
        if (msg.dePlayerData) {
            let h = utils.simpleHashWithKey(msg.dePlayerData, 'q56789abc')
            if (h !== msg.h) {
                postMessage({ fmessageID: msg.fmessageID })
                return
            }
            let playerCopy = deMessageCb(msg.dePlayerData, 'qihuan')
            fuserData.playerCopy = playerCopy
            plen = playerCopy.length
            let player = new PlayerModel(JSON.parse(fuserData.playerCopy))
            fuserData.playerStrH = utils.simpleHashWithKey(JSON.stringify(player.baseInfo) + JSON.stringify(player.itemInfo) + JSON.stringify(player.bag), 'player578')
            postMessage({ fmessageID: msg.fmessageID, err: 0, data: playerCopy })
        } else if (msg.rName) {
            let t = new Date().getTime()
            if (!fuserData.setConfigTime || msg.time - fuserData.setConfigTime > 2000) {
                gameConfigHandle.setConfig()
                fuserData.setConfigTime = msg.time
            }
            let player = new PlayerModel(JSON.parse(fuserData.playerCopy))
            let playerStrH = utils.simpleHashWithKey(JSON.stringify(player.baseInfo) + JSON.stringify(player.itemInfo) + JSON.stringify(player.bag), 'player578')
            if (playerStrH !== fuserData.playerStrH || plen !== fuserData.playerCopy.length) {
                postMessage({ fmessageID: msg.fmessageID, err: 1 });
                return
            }
            let gameRouteData: GameRouteData = {
                player: player,
                random: new Random(msg.s),
                time: msg.time,
                dayTime: msg.dayTime,
                vipLvl: msg.vipLvl,
                isMonthVip: msg.isMonthVip,
                isYearVip: msg.isYearVip,
                version: msg.version
            }
            if (msg.rName == "cheatRoute") {
                postMessage({ fmessageID: msg.fmessageID, err: 1 });
                return
            }
            if (msg.rName == "normalRoute" && msg.fName == "getMail") {
                let data = msg.data[0]
                let h = msg.data[1]
                let dataStr = JSON.stringify(data)
                let _h = utils.simpleHashWithKey(dataStr, 'mail23456')
                if (h !== _h) {
                    postMessage({ fmessageID: msg.fmessageID, err: 1 });
                    return
                }
            }
            let res = route[msg.rName][msg.fName](...msg.data, gameRouteData)
            let itemBagStr = JSON.stringify(gameRouteData.player.baseInfo) + JSON.stringify(gameRouteData.player.itemInfo) + JSON.stringify(gameRouteData.player.bag) + msg.pID
            gameRouteData.player["time"] = msg.time
            gameRouteData.player["id"] = msg.pID
            gameRouteData.player["version"] = msg.version
            gameRouteData.player["flag"] = 2
            let rIndex = msg.rMapData[msg.rName + "_" + msg.fName]
            gameRouteData.player.rMapTime[rIndex] = (gameRouteData.player.rMapTime[rIndex] || 0) + 1
            fuserData.playerStrH = utils.simpleHashWithKey(JSON.stringify(gameRouteData.player.baseInfo) + JSON.stringify(gameRouteData.player.itemInfo) + JSON.stringify(gameRouteData.player.bag), 'player578')
            // if (msg.itemStr !== itemBagStr) {
            //     gameRouteData.player.ch.c2 += 1
            // }
            let playerCopy = JSON.stringify(gameRouteData.player)
            fuserData.playerCopy = playerCopy
            plen = playerCopy.length
            fuserData.waitEncodeData = playerCopy
            postMessage({ fmessageID: msg.fmessageID, err: res.err })
        }
    } else if (msg.encode) {
        if (fuserData.waitEncodeData) {
            let player = new PlayerModel(JSON.parse(fuserData.waitEncodeData))
            let playerStrH = utils.simpleHashWithKey(JSON.stringify(player.baseInfo) + JSON.stringify(player.itemInfo) + JSON.stringify(player.bag), 'player578')
            if (playerStrH !== fuserData.playerStrH || plen !== fuserData.waitEncodeData.length) {
                postMessage({ fmessageID: msg.fmessageID, err: 1 });
                return
            }
            let playerCopyEncode = enMessageCb(fuserData.waitEncodeData, 'qihuan')
            let h = utils.simpleHashWithKey(playerCopyEncode, 'q56789abc')
            fuserData.waitEncodeData = null
            postMessage({ playerData: playerCopyEncode, h, savePlayer: msg.savePlayer });
        } else {
            postMessage({ savePlayer: msg.savePlayer });
        }
    }
}



